//
//  RunDetailViewModel.swift
//  MoyoungHome
//
//  Created by 易先生 on 2022/9/27.
//

import UIKit
import RxCocoa
import RxSwift
import MYModule
import SwiftDate
import CRPSmartRing

open class TrainingDetailViewModel: NSObject {

    public var type: TrainingType = .unknown
    
    public let trainingModelRelay = BehaviorRelay<TrainingModel?>(value: nil)

	public let heartRateZoneRelay = BehaviorRelay<HeartRateZoneModel>(value: HeartRateZoneModel())

	public let runTimeRelay = BehaviorRelay<TrainingDetailWorkoutsRecordModel?>(value: nil)

	public var sliderEnd: Driver<Void>?
    
	
    public init(type: TrainingType, startTime: Int) {
        super.init()
        
        self.type = type
        
        guard let trainModel = TrainingModel.model(of: type.rawValue, startTime: startTime) else {
            return
        }
        
        getDayDatas(trainModel: trainModel)
    }
    
    public init(trainModel: TrainingModel) {
        super.init()
        
        if let type = TrainingType(rawValue: trainModel.type) {
            switch type {
            case .gps_Run, .gps_TrailRun:
                self.type = .running
            case .gps_Cycling:
                self.type = .cycling
            case .gps_Onfoot, .gps_Walking:
                self.type = .walking
            default:
                self.type = type
            }
        }
        getDayDatas(trainModel: trainModel)
    }

    private func getDayDatas(trainModel: TrainingModel?) {
        
        guard let trainModel = trainModel else {
            return
        }
        
        self.trainingModelRelay.accept(trainModel)
        
        var dataSource: [Double] = trainModel.heartRates.map({ Double($0) })

		if dataSource.count < 2 {
			if let heartValue = dataSource.first {
				dataSource.append(heartValue)
			}
		}

		format.locale = Locale.current
		format.dateFormat = "HH:mm"
        
		// 运动详情
		getTotalTimeDatas(traniningModel: trainModel)

		// 心率数据分析
        heartDataAnalysis(hearts: trainModel.heartRates)

	}

    private func getTotalTimeDatas(traniningModel: TrainingModel?) {
        
        guard let model = traniningModel else {
            return
        }
        
        if model.startTime <= 0 {
            return
        }
        
        let format = DateFormatter()
        format.dateFormat = getHomeTimeFormat()
        format.calendar = Calendar.init(identifier: .gregorian)
        
        let vaildTime = model.vaildTime
        
        let distance = Double(model.distance)
        let step = model.step
        let km = distance / 1000.0
        let kcal = model.kcal
        
        var pace = 0.0
        if km != 0 {
            if Unit.sharedInstance.myType == .metric {
                pace = (Double(vaildTime) / 60.0) / km
            } else {
                pace = (Double(vaildTime) / 60.0) / ((distance * 100 / 16093) / 10.0)
            }
        }
        
        
        let execiseModel = TrainingDetailWorkoutsRecordModel()
        execiseModel.type = self.type
        execiseModel.distance = km
        execiseModel.time = vaildTime
        execiseModel.trainingModel = model
        
        if let goalType = CRPTrainingGoalType(rawValue: model.goalType)?.trainingContentType {
            
            if goalType == .time {
                execiseModel.goalTime = model.goal
            }
            if goalType == .distance {
                execiseModel.goalDistance = CGFloat(model.goal)/1000.0
            }
            switch goalType {
            case .unkown:
                execiseModel.progress = 0.0
            case .distance:
                execiseModel.progress = CGFloat(model.distance) / CGFloat(model.goal)
            case .time:
                execiseModel.progress = CGFloat(model.vaildTime) / CGFloat(model.goal)
            case .pace:
                // 目标配速是进度条的一半，配速为0时，进度条在最左侧，配速在0-目标配速时，在中心点右侧；配速在目标配速-目标配速*2时，在中心点左侧
                var progress = 0.0
                if pace <= 0.0 {
                    progress = 0.0
                } else  if pace >= CGFloat(model.goal) * 2.0 {
                    progress =  0.0
                } else if pace >= CGFloat(model.goal) {
                    progress =  0.5 - (pace - CGFloat(model.goal)) / (CGFloat(model.goal) * 2)
                } else if pace < CGFloat(model.goal) {
                    progress =  0.5 + (CGFloat(model.goal) - pace ) / (CGFloat(model.goal) * 2)
                } else {
                    progress =  0.0
                }
                if progress > 1.0 {
                    progress = 1.0
                }
                if progress < 0.0 {
                    progress = 0.0
                }
                execiseModel.progress = progress
            case .calorie:
                execiseModel.progress = CGFloat(model.kcal) / CGFloat(model.goal)
            case .step:
                execiseModel.progress = CGFloat(model.step) / CGFloat(model.goal)
            case .heartRate:
                execiseModel.progress = CGFloat(model.heartRateAvg) / CGFloat(model.goal)
            }
            
        }
        
        let contentTypes = self.type.contents
        
        if contentTypes.contains(.calorie) {
            execiseModel.caloriesData = TrainingDetailTotalDataSubModel(iconName: "ic_workout_popular_calories", value: "\(kcal.normalTitle)", unit: "gps_training_kcal".language, title: "training_rate_total_calories".language)
        }
        
        if contentTypes.contains(.pace) {
            let pace_tuple = Unit.sharedInstance.timeOf(seconds:  Int(pace * 1000.0 * 60.0)/1000, granularity: .minute)
            var paceStr = "\(pace_tuple.minute.leadingZero)'\(pace_tuple.second.leadingZero)\""
            if pace_tuple.minute == 0 && pace_tuple.second == 0 {
                paceStr = "--'--\""
            }
            execiseModel.paceData = TrainingDetailTotalDataSubModel(iconName: "ic_workout_popular_pace", value: paceStr, unit: "gps_training_goal_setting_pace_current_unit".language, title: "training_pace".language)
        }
        
        if contentTypes.contains(.step) {
            execiseModel.stepsData = TrainingDetailTotalDataSubModel(iconName: "ic_workout_popular_steps", value: "\(step.normalTitle)", unit: "", title: "gps_training_finish_total_steps".language)
        }
        
        if contentTypes.contains(.heartRate) {
            execiseModel.heartRateData = TrainingDetailTotalDataSubModel(iconName: "ic_workout_popular_hr", value: "\(model.heartRateAvg.normalTitle)", unit: "training_bpm_unit".language, title: "training_detail_item_avg_heart_rate_title".language)
        }
        
        runTimeRelay.accept(execiseModel)
        
    }
    
    private func heartDataAnalysis(hearts: [Int]) {
        let heartRateZoneModel = HeartRateZoneModel.calculationMinute(with: hearts, heartRateInterval: 10, componet: .second)
		heartRateZoneRelay.accept(heartRateZoneModel)
	}
    
    public lazy var format: DateFormatter = {
        let format = DateFormatter()
        format.calendar = Calendar.init(identifier: .gregorian)
        format.dateFormat = "HH:mm"
        return format
    }()

	
}

extension TrainingDetailViewModel {
    
    
    public func amIsFront() ->Bool{
        if let formatStringForHours = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current){
            let index = formatStringForHours.positionOf(sub: "a")
            if index > -1 && index < 2 {
                return true
            }
        }
        return false
    }
    
    public func getHomeTimeFormat() -> String{
        var format = "yyyy-MM-dd HH:mm"
        let formatStrigForHours = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale.current)
        if let hasAMPM = formatStrigForHours?.contains("a"), hasAMPM == true{
            if amIsFront(){
                format = "yyyy-MM-dd a hh:mm"
            }else {
                format = "yyyy-MM-dd hh:mm a"
            }
        }
        return format
    }
    
    
}
